
/****************************************************************************/

int kernelMultitaskerGetIOPerm(int processId, int portNum)
{
	// Check if the given process can use I/O ports specified.  Returns 1 if
	// permission is allowed.

	int status = 0;
	kernelProcess *ioProcess = NULL;

	// Make sure multitasking has been enabled
	if (!multitaskingEnabled)
		return (status = ERR_NOTINITIALIZED);

	if (portNum >= IO_PORTS)
		return (status = ERR_BOUNDS);

	ACQUIRE_LOCK_PROCESS_QUEUE();

	ioProcess = getProcessById(processId);
	if (ioProcess == NULL)
	{
		// There's no such process
		RELEASE_LOCK_PROCESS_QUEUE();
		kernelError(kernel_error, "No process %d to get IO permissions", processId);
		return (status = ERR_NOSUCHPROCESS);
	}

	// If the bit is set, permission is not granted.
	if (GET_PORT_BIT(ioProcess->taskStateSegment.IOMap, portNum))
		status = 0;
	else
		status = 1;

	RELEASE_LOCK_PROCESS_QUEUE();

	return (status);
}

/****************************************************************************/

int kernelMultitaskerSetIOPerm(int processId, int portNum, int yesNo)
{
	// Allow or deny I/O port permission to the given process.

	int status = 0;
	kernelProcess *ioProcess = NULL;

	// Make sure multitasking has been enabled
	if (!multitaskingEnabled)
		return (status = ERR_NOTINITIALIZED);

	if (portNum >= IO_PORTS)
		return (status = ERR_BOUNDS);

	ACQUIRE_LOCK_PROCESS_QUEUE();

	ioProcess = getProcessById(processId);
	if (ioProcess == NULL)
	{
		// There's no such process
		RELEASE_LOCK_PROCESS_QUEUE();
		kernelError(kernel_error, "No process %d to set IO permissions", processId);
		return (status = ERR_NOSUCHPROCESS);
	}

	if (yesNo)
		UNSET_PORT_BIT(ioProcess->taskStateSegment.IOMap, portNum);
	else
		SET_PORT_BIT(ioProcess->taskStateSegment.IOMap, portNum);

	RELEASE_LOCK_PROCESS_QUEUE();

	return (status = 0);
}

/****************************************************************************/
